use core::fmt::Write;

use alloc::boxed::Box;
use os_terminal::{
    font::{BitmapFont, TrueTypeFont},
    Terminal,
};
use spin::{Lazy, Mutex};
use x86_64::instructions::interrupts;

use crate::display::Display;

pub static TERMINAL: Lazy<Mutex<Terminal<Display>>> = Lazy::new(|| {
    let mut terminal = Terminal::new(Display::new());
    terminal.set_font_manager(Box::new(BitmapFont));
    Mutex::new(terminal)
});

pub fn set_font(size: f32, font: &'static [u8]) {
    TERMINAL
        .lock()
        .set_font_manager(Box::new(TrueTypeFont::new(size, font)));
}

#[inline]
pub fn _print(args: core::fmt::Arguments) {
    interrupts::without_interrupts(|| {
        TERMINAL.lock().write_fmt(args).unwrap();
    })
}

#[macro_export]
macro_rules! print {
    ($($arg:tt)*) => (
        $crate::terminal::_print(
            format_args!($($arg)*)
        )
    )
}

#[macro_export]
macro_rules! println {
    () => ($crate::print!("\n"));
    ($($arg:tt)*) => ($crate::print!("{}\n", format_args!($($arg)*)))
}
